package scantask.client.presentationLayer;

import gov.nasa.worldwind.WorldWindow;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.AirspaceLayer;
import gov.nasa.worldwind.render.airspaces.Polygon;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;

import scantask.client.domainLayer.ControllerInterface;
import scantask.containers.Area;
import scantask.containers.Coordinate;
import scantask.containers.InformationObject;
import scantask.containers.WeekDate;
import scantask.containers.exceptions.InvalidWeekNumberException;
import scantask.containers.exceptions.InvalidYearException;
import scantask.containers.exceptions.MissingLayerException;
import scantask.containers.exceptions.UnInitializeObjectException;
import scantask.server.domainLayer.Exceptions.ControllerException;
import scantask.server.domainLayer.Exceptions.LoginException;

public class LoginPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// The world window of NASA.
	private WorldWindow _wwd;
	
	// The client controller.
	private ControllerInterface _controller;
	
	// Layers for shapes.
	private Map<String, AirspaceLayer> _layers;
	
	public LoginPanel(WorldWindow wwd, ControllerInterface controller, 
			Map<String, AirspaceLayer> layers)
    {
		super();
		this.setLayout(null);
		this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
		
        this._wwd = wwd;
        this._controller = controller;
        this._layers = layers;
        
        JLabel user = new JLabel();
        user.setText("Username:");
        user.setBounds(10, 10, 100, 25);
        this.add(user);
        
        final JTextArea usernameText = new JTextArea();
        usernameText.setBounds(10, 45, 100, 25);
        this.add(usernameText);
        
        JLabel password = new JLabel();
        password.setText("Password:");
        password.setBounds(10, 80, 100, 25);
        this.add(password);
        
        final JPasswordField passwordText = new JPasswordField();
        passwordText.setBounds(10, 115, 100, 25);
        this.add(passwordText);
        
        // Button for login.
        JButton login = new JButton("Login");
        login.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String user = usernameText.getText();
				String pass = new String(passwordText.getPassword());
				try {
					LoginPanel.this._controller.login(user, pass);
					JOptionPane.showMessageDialog(
							null, "Welcome...",
							"Login succeeded  ", JOptionPane.INFORMATION_MESSAGE);
					usernameText.setText("");
					passwordText.setText("");
					LoginPanel.this.initAfterLogin();
					UpperPanel.updateShowHidePanel(LoginPanel.this._layers);
					FunctionalityPanel.changePanels();
					UpperPanel.changePanels();
				} catch (ControllerException e) {
					usernameText.setText("");
					passwordText.setText("");
					JOptionPane.showMessageDialog(
							null, "Wrong user name or password",
							"Error  ", JOptionPane.ERROR_MESSAGE);
				}
			}
		});
        login.setBounds(10, 150, 100, 25);
        this.add(login);
        
        this._wwd.getView().setEyePosition(new Position(
				LatLon.fromDegrees(36, 15),
				27000000));
        
    }
	
	private void initAfterLogin(){
		Vector<WeekDate> dates = new Vector<WeekDate>();
		Vector<InformationObject> objects = new Vector<InformationObject>();
		try {
			dates = this._controller.getValidDates();
			if ( (dates != null) && (dates.size() > 0)){
				this.createAreasLayer();
				objects = this._controller.viewHistory(
						dates.get(dates.size()-1).getYear(),
						dates.get(dates.size()-1).getWeek());
				Set<String> types = this._controller.getDataTypes();
				Iterator<String> typesIter = types.iterator();
				while(typesIter.hasNext()){
					String type = typesIter.next(); 
					if(type.startsWith("SyntheticObject")){
						if(!this._layers.containsKey("SyntheticObject")){
							AirspaceLayer l = new AirspaceLayer();
							Presentation.insertBeforeCompass(
									this._wwd, l);
							this._layers.put("SyntheticObject", l);
						}
					}
					else{
						AirspaceLayer l = new AirspaceLayer();
						Presentation.insertBeforeCompass(
								this._wwd, l);
						this._layers.put(type, l);
					}
				}
				this._controller.
						setPolygonesLayers(this._layers);
				for(int i = 0; i<objects.size(); i++){
					objects.elementAt(i).getPolygone().draw();
				}
			}
			Coordinate coor = this._controller.getDefaultCoordinate();
			this._wwd.getView().goTo(new Position(
					LatLon.fromDegrees(coor.getY(), coor.getX()),
					FunctionalityPanel.DEFAULT_ZOOM),
					FunctionalityPanel.DEFAULT_ZOOM);
		} catch (LoginException e) {
		} catch (InvalidWeekNumberException e) {
		} catch (InvalidYearException e) {
		} catch (UnInitializeObjectException e) {
		} catch (MissingLayerException e) {
		} catch (ControllerException e) {
		}
		this.update();
	}
	
	public void createAreasLayer(){
		Vector<Area> areas;
		try {
			areas = this._controller.getUserAreas();
			AirspaceLayer areasLayer = new AirspaceLayer();
			Presentation.insertBeforeCompass(
					this._wwd, areasLayer);
			this._layers.put("Areas", areasLayer);
			for(int i = 0; i<areas.size(); i++){
				Vector<Coordinate> coors = areas.get(i).getVertixes();
				List<LatLon> coorsList = new LinkedList<LatLon>();
				String name = areas.get(i).getName();
				String type = areas.get(i).getType();
				for (int j = 0; j<coors.size(); j++){
					coorsList.add(LatLon.fromDegrees(
							coors.get(j).getY(), coors.get(j).getX()));
				}
				Polygon pol = new Polygon(coorsList);
				pol.setAltitudes(0, FunctionalityPanel.DEFAULT_AREA_HEIGHT);
				pol.setDescription("Area: " + name + "\nType: " + type);
				Presentation.AppFrame.setAreaAttr(pol, areas.get(i).getColor(), Color.BLACK);
				areasLayer.addAirspace(pol);
			}
		} catch (LoginException e) {
		} catch (UnInitializeObjectException e) {
		}
	}
	
	// Update Globe.
    private void update()
    {
        this._wwd.redraw();
    }
}
